package com.me.seckill.controller;

import com.crossoverjie.distributed.annotation.SpringControllerLimit;
import com.me.seckill.pojo.Stock;
import com.me.seckill.service.OrderService;
import com.me.seckill.service.StockService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * 秒杀 controller
 */
@RestController
@RequestMapping(produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class SeckillController {

    private static final Logger logger = LoggerFactory.getLogger(SeckillController.class);

    @Autowired
    private StockService stockService;

    @Autowired
    private OrderService orderService;

    @RequestMapping("/health")
    public String health() {
        logger.info("heath");

        return "OK";
    }

    /**
     * 初始化秒杀商品信息，及 Redis库存
     *
     * @return 初始库存信息
     */
    @RequestMapping("/setStockNum")
    @ResponseBody   // 自动配置了 MappingJackson2HttpMessageConverter 所以才能返回 Integer
    public Integer setStockNum() {
        int currentCount = 0;
        try {
            int sid = 1;
            Stock stock = new Stock(sid, "手机", 10, 0, 0);
            int delCount = orderService.deleteByStockId(sid);
            logger.debug("根据 {} 删除了 {} 条订单", sid, delCount);
            stockService.delStock(stock);
            stockService.initStock(stock);
            currentCount = stockService.setRedisStock(sid);
        } catch (Exception e) {
            logger.error("Exception", e);
        }
        logger.info("currentCount = {}", currentCount);

        // return String.valueOf(currentCount);
        return currentCount;
    }

    /**
     * 5、乐观锁更新库存 + 限流 + Redis库存 + MQ异步创建订单
     *
     * @param sid 秒杀商品id
     */
    @SpringControllerLimit
    @RequestMapping("/createLimitOrderByRedisAndMQ/{sid}")
    public String createLimitOrderByRedisAndMQ(@PathVariable int sid) {
        logger.info("秒杀商品ID [{}]", sid);
        orderService.createOptimisticOrderUseRedisAndMQ(sid);

        return "success";
    }

    /**
     * 4、乐观锁更新库存 + 限流 + Redis库存
     *
     * @param sid 秒杀商品id
     * @return  订单ID
     */
    @SpringControllerLimit(errorCode = 200, errorMsg = "request has limited")
    @RequestMapping("/createLimitOrderByRedis/{sid}")
    public String createLimitOrderByRedis(@PathVariable int sid) {
        logger.info("秒杀商品ID [{}]", sid);
        int id = 0;
        try {
            id = orderService.createOptimisticOrderUseRedis(sid);
        } catch (Exception e) {
            logger.error("Exception",e);
        }

        return String.valueOf(id);
    }

    /**
     * 3、乐观锁更新库存 + 限流
     *
     * @param sid 秒杀商品id
     * @return  订单ID
     */
    @SpringControllerLimit(errorCode = 200)
    @RequestMapping("/createLimitOrder/{sid}")
    public String createLimitOrder(@PathVariable int sid) {
        logger.info("秒杀商品ID [{}]", sid);
        int id = 0;
        try {
            id = orderService.createOptimisticOrder(sid);
        } catch (Exception e) {
            logger.error("Exception",e);
        }

        return String.valueOf(id);
    }

    /**
     * 2、乐观锁更新库存
     *
     * @param sid 秒杀商品id
     * @return  订单ID
     */
    @RequestMapping("/createOrder/{sid}")
    public String createOrder(@PathVariable int sid) {
        logger.info("秒杀商品ID [{}]", sid);
        int id = 0;
        try {
            id = orderService.createOptimisticOrder(sid);
        } catch (Exception e) {
            logger.error("Exception",e);
        }

        return String.valueOf(id);
    }

    /**
     * 1、超卖下单接口
     *
     * @param sid 秒杀商品id
     * @return  订单ID
     */
    @RequestMapping("/createWrongOrder/{sid}")
    public String createWrongOrder(@PathVariable int sid) {
        logger.info("秒杀商品ID [{}]", sid);
        int id = 0;
        try {
            id = orderService.createWrongOrder(sid);
        } catch (Exception e) {
            logger.error("Exception",e);
        }

        return String.valueOf(id);
    }

}
